package pers.cz.commons.rank;

import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 构造排行榜列表，使用双向链表实现
 * @program: PostGirl-panent
 * @description: Rank
 * @author: Cheng Zhi
 * @create: 2021-09-23 16:30
 **/
@Component
public class Rank<K,V> {
    private int capcity = 10; // 总容量
    private int currentSize = 0; // 当前容量
    private Node firstNode; // 头节点
    private Node lastNode; // 尾节点
    private Map<K,Node> caches = new HashMap<K,Node>(10); // 榜单

    /**
     * 新增节点（先判断榜单上是否存在该节点，如果存在，则排名提升到第一，如果不存在，插入到链表头，同时删除尾节点）
     * @param key
     * @param value
     */
    public void add(K key, V value) {

        Node node = caches.get(key);
        if (node == null) {
            // 新增节点
            if (caches.size() >= capcity) {

                // 移除最后一个节点
                caches.remove(lastNode.key);
                // 组织移除后的节点关系
                lastNode = lastNode.prev;
                lastNode.next = null;
            }

            // 插入新节点
            node = new Node(key, value);

            // 组织插入后的节点关系
            node.next = firstNode;

            if (node.next == null) {
                lastNode = node;
            } else {
                node.next.prev = node;
            }
            firstNode = node;
            currentSize ++;
        } else {

            // 插入已存在的节点
            if (node == firstNode) {
                return;
            }
            node.val = value;

            if (node.prev != null) {
                node.prev.next = node.next;
            }
            if (node.next != null) {
                node.next.prev = node.prev;
            }
            node.next = firstNode;
            node.next.prev = node;
            firstNode = node;
        }
        caches.put(key, node);
    }

    /**
     * 移除节点（先判断榜单上是否存在该节点，如果存在则删除同时改变该节点的前驱和后继）
     * @param key
     */
    public void remove(K key) {

        Node node = caches.get(key);

        if (node == null) {
            return;
        }

        node.prev.next = node.next;
        if (node.next != null) {
            node.next.prev = node.prev;
        }

        caches.remove(key);
    }

    /**
     * 获取榜单
     */
    public List<String> getRank() {

        List<String> lists = new ArrayList<String>();
        Node node = firstNode;
        while (node != null) {
            lists.add((String) node.val);
            node = node.next;
        }

        return lists;
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        Node node = firstNode;
        while (node != null) {
            sb.append(String.format("%s:%s ", node.key, node.val));
            node = node.next;
        }
        return sb.toString();
    }
}
